package com.imc.api.appointment.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.imc.api.order.pojo.Lesson;
import com.imc.api.templmess.pojo.*;
import com.imc.api.templmess.service.TemplateService;
import com.imc.api.templmess.service.http.ITempMessService;
import com.imc.api.templmess.utils.TemplateData;
import com.imc.api.templmess.utils.WeiXinEnum;
import com.imc.core.annotation.Logs;
import com.imc.core.utils.MysqlUtil;
import com.imc.platform.base.appointment.pojo.Appointment;
import com.imc.platform.base.appointment.service.IAppointmentService;
import com.imc.platform.base.lesson.service.LessonService;
import com.imc.platform.base.org.pojo.Org;
import com.imc.platform.base.user.pojo.User;
import com.imc.platform.base.user.service.IUserService;
import com.twp.common.component.process.exception.combo.IComboExecptionForTFunc;
import com.twp.common.tuple.ResultDTO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 * 类描述：预约小程序接口控制类
 * 开发者：YT
 * 创建日期：2018/10/27 22:37
 */
@Slf4j
@RestController
@RequestMapping("/api/appointment")
public class AppointmentApiController {

    @Autowired
    IComboExecptionForTFunc iComboExecptionForTFunc;//基本服务操作类

    @Autowired
    IAppointmentService appointmentService;//预约服务

    @Autowired
    TemplateService iTempMessService;//模板消息服务

    @Autowired
    IUserService iUserService;//用户服务

    @Autowired
    LessonService lessonService;//课程服务

    @Autowired
    MysqlUtil mysqlUtil;//通用处理

    @Autowired
    NotifyPropertyConfig notifyPropertyConfig;

    /*
     * YT  2018/10/27 22:39
     * 方法描述：传参对象
     */
    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    public static class ReqTuple {
        Map <String, String> parmsMap;
    }

    /*
     * YT  2018/10/17 23:38
     * 方法描述：根据ID查询预约信息
     */
    @GetMapping("/queryAppointmentById")
    @ResponseBody
    public ResultDTO queryAppointmentById(Principal principal,@RequestParam String id) {
        return iComboExecptionForTFunc.executeFlow(
                ResultDTO.builder().message("获取详情信息成功").build(),
                t -> {
//                    User user = mysqlUtil.getUserByLoginNameCommon(principal.getName());
                    log.info("principal.getName():"+principal.getName());
                    User user=iUserService.queryUserByLoginName1(principal.getName());
                    Appointment appointment = appointmentService.queryAppointmentInfoById(id);
                    if(null!=appointment.getApproverId() && !String.valueOf(user.getId()).equals(appointment.getApproverId())){
                        appointment.setIsDealPerson("false");
                    }else{
                        appointment.setIsDealPerson("true");
                    }
                    t.setData(appointmentService.queryAppointmentInfoById(id));
                },
                (e, t) -> {
                    e.printStackTrace();
                    t.setIsSuccess(false);
                    t.setMessage("获取详情信息失败");
                }
        );
    }

    /**
     * QY 2018/9/3 10:16
     * 方法描述：更改状态
     **/
    @PostMapping("/updateState")
    @ResponseBody
    public ResultDTO updateState(@RequestBody Appointment appointment) {
        return iComboExecptionForTFunc.executeFlow(
                ResultDTO.builder().message("更新状态成功").build(),
                t -> {
                    String state = appointment.getState();
                    int id = appointment.getId();
                    t.setData(appointmentService.updateState(state, String.valueOf(id)));
                    Appointment appointment1 = appointmentService.queryAppointmentInfoById(String.valueOf(id));
                    appointment1.setPage(appointment.getPage());
//                    appointment1.setFormId(appointment.getFormId());
                    User user = iUserService.queryUserById(appointment1.getUserId());
                    try {
                        Map <String, TemplateData> param = new HashMap <>();
                        param.put("keyword1", new TemplateData(StringUtils.isEmpty(appointment.getSubscriber())?user.getTrueName():appointment.getSubscriber(), "#696969"));
                        param.put("keyword2", new TemplateData(user.getTel(), "#696969"));
                        String addr="";
                        if(!StringUtils.isEmpty(appointment1.getLessonId())){
                            Lesson lesson = lessonService.queryLessonDetByLessonId(appointment1.getLessonId());
                            log.info(JSON.toJSONString(lesson));
                            if (lesson != null) {
                                addr=lesson.getAddress();
                            }
                        }
                        param.put("keyword3", new TemplateData(addr, "#696969"));
                        param.put("keyword4", new TemplateData(appointment1.getFormId(), "#696969"));
                        param.put("keyword5", new TemplateData(appointment1.getState() == "0" ? "未处理" : "已处理", "#696969"));
                        TempMall tempMall=TempMall.builder()
                                .access_token(iTempMessService.getAccessToken(Token.builder()
                                        .appid(notifyPropertyConfig.getAppid())
                                        .secret(notifyPropertyConfig.getAppsecret())
                                        .grant_type("client_credential")
                                        .build()))
                                .touser(user.getOpenId())
                                .weapp_template_msg(Weapp_template_msg.builder()
                                        .template_id(notifyPropertyConfig.getAppAddress().getAppointTempletId())
                                        .emphasis_keyword("")
                                        .form_id(appointment1.getFormId())
                                        .page("pages/tabbar/appointment/detail/index?id="+appointment1.getId())
                                        .data(param)
                                        .build())
                                .build();
                        JSONObject jsonObject= iTempMessService.messSend(tempMall);
                        log.info(jsonObject.toString());
//                        sendTempMess(appointment1, id, user, notifyPropertyConfig.getAppid(),notifyPropertyConfig.getAppsecret());
                    } catch (Exception e) {
                        log.error("e:", e.getMessage());
                    }
                },
                (e, t) -> {
                    e.printStackTrace();
                    t.setIsSuccess(false);
                    t.setMessage("更新状态失败");
                }
        );
    }

    /*
     * YT  2018/10/24 18:41
     * 方法描述：根据预约用户获取预约单信息列表(一个用户可能多个预约信息。支持所有条件查询)
     * 不分页。全部取出数据
     */
    @PostMapping("/find")
    ResultDTO getAppointmentsListNoPage(@RequestBody Appointment appointment) {
        return iComboExecptionForTFunc.executeFlow(
                ResultDTO.builder().build(),
                t -> {
                    t.setData(appointmentService.getAppointmentListNoPage(appointment));
                },
                (e, t) -> {
                    e.printStackTrace();
                    t.setIsSuccess(false);
                    t.setMessage("获取失败");
                }
        );
    }

    /*
     * YT  2018/10/24 18:41
     * 方法描述：根据预约用户获取预约单信息列表(一个用户可能多个预约信息。支持所有条件查询)
     * 分页。支持3条数据
     */
    @PostMapping("/list")
    ResultDTO getAppointmentsListPage(Principal principal, @RequestBody final Appointment appointment, @PageableDefault(size = 3) Pageable pageable) {
        User user = mysqlUtil.getUserByLoginNameCommon(principal.getName());
        if (null != appointment) {
            //校长，总校长，获取总校长，校长的userID就是处理人ID
            if ("3".equals(user.getRoleId()) || "2".equals(user.getRoleId())) {
                appointment.setApproverId(String.valueOf(user.getId()));//处理人ID
            } else if ("0".equals(user.getRoleId())) {
                //管理员不限制查询所有的
            } else if ("4".equals(user.getRoleId())) {
                //老师老师ID就是处理人ID
                appointment.setApproverId(String.valueOf(user.getId()));//处理人ID
            } else {
                //如果是学生就是当前用户ID
                appointment.setUserId(String.valueOf(user.getId()));  //当前用户ID
            }
            return iComboExecptionForTFunc.executeFlow(
                    ResultDTO.builder().build(),
                    t -> {
                        t.setData(appointmentService.getAppointmentListPage(appointment, pageable));
                    },
                    (e, t) -> {
                        e.printStackTrace();
                        t.setIsSuccess(false);
                        t.setMessage("获取失败");
                    }
            );
        } else {
            final Appointment appointment1 = new Appointment();
            //校长，总校长
            if ("3".equals(user.getRoleId()) || "2".equals(user.getRoleId())) {
                appointment1.setApproverId(String.valueOf(user.getId()));//处理人ID
            } else if ("0".equals(user.getRoleId())) {
                //管理员
            } else if ("4".equals(user.getRoleId())) {
                //老师
                appointment1.setApproverId(String.valueOf(user.getId()));//处理人ID
            } else {
                appointment1.setUserId(String.valueOf(user.getId()));  //当前用户ID
            }
            return iComboExecptionForTFunc.executeFlow(
                    ResultDTO.builder().build(),
                    t -> {
                        t.setData(appointmentService.getAppointmentListPage(appointment1, pageable));
                    },
                    (e, t) -> {
                        e.printStackTrace();
                        t.setIsSuccess(false);
                        t.setMessage("获取失败");
                    }
            );
        }

    }

    /*
     * YT  2018/10/27 22:41
     * 方法描述：查询已经预约过的课时
     */
    @GetMapping("/scheduleList")
    ResultDTO queryLessonSchedulerByLessonId(@RequestParam String lessonId, Principal principal) {
        User user = mysqlUtil.getUserByLoginNameCommon(principal.getName());
        return iComboExecptionForTFunc.executeFlow(
                ResultDTO.builder().build(),
                t -> {
                    t.setData(appointmentService.queryLessonSchedulerByLessonId(lessonId, String.valueOf(user.getId())));
                },
                (e, t) -> {
                    e.printStackTrace();
                    t.setIsSuccess(false);
                    t.setMessage("获取失败");
                }
        );
    }

    @Value("${pay.appid}")
    String appid;
    @Value("${pay.appsecret}")
    String appsecret;

    /*
     * YT  2018/10/24 0:20
     * 方法描述：发起预约，预约成功之后发送模板消息给预约人。现在没有发送给处理人。
     * 处理人就是当前小区的校长的ID
     */
    @Logs
    @PostMapping("")
    ResultDTO postAppointment(Principal principal, @RequestBody Appointment appointment) {
        return iComboExecptionForTFunc.executeFlow(
                ResultDTO.builder().message("发起预约成功").build(),
                t -> {
                    try {
                        log.info("appointment:"+ JSON.toJSONString(appointment));
                        appointment.setBirthday(appointment.getBirthDate());
                        //查询用户信息
                        String uname = principal.getName();
                        User user = mysqlUtil.getUserByLoginNameCommon(uname);
                        appointment.setUserId(String.valueOf(user.getId()));
                        String currentUserId = String.valueOf(user.getId());
                        log.info("uname:"+ uname);
                        log.info("userId1:"+ String.valueOf(user.getId()));
                        if (null != appointment.getLessonId() && !"".equals(appointment.getLessonId())) {
                            //如果有课程就是拿课程ID，获取对应校区的校长ID就是处理人
                            Org org = appointmentService.queryOrgIdByLessonId(appointment.getLessonId());
                            appointment.setOrgId(org.getId());
                            String userId = appointmentService.queryUserByOrgId(org.getId());
                            appointment.setApproverId(userId);
                            log.info("userId2:"+ user.getId());
                        } else {
                            //如果没有课程就是首页预约，并没有实质性的预约特定的课程，就是一个简单的预约
                            //直接前台预约的时候传一个校区ID过来
                            appointment.setOrgId(appointment.getOrgId());
                            String userId = appointmentService.queryUserByOrgId(appointment.getOrgId());
                            appointment.setApproverId(userId);
                            log.info("userId3:"+ user.getId());
                        }

                        user = iUserService.queryUserById(appointment.getApproverId());
                        log.info("userId4:"+ user.getId());
                        //有课程就是入课程，课时信息，课时可多选，对应多条记录
                        String bnId = "";
                        if (null != appointment.getLessonScheduleIds() && appointment.getLessonScheduleIds().length > 0) {
                            String[] lessonScheduleIds = appointment.getLessonScheduleIds();
                            boolean flag = false;
                            for (String lessonScheduleId : lessonScheduleIds) {
                                log.info("lessonScheduleId:"+ lessonScheduleId);
                                appointment.setLessonScheduleId(lessonScheduleId);
                                List <Appointment> list = appointmentService.queryAppointmentExists(appointment);
                                if (list.size() > 0) {
                                    flag = true;
                                    break;
                                }
                            }
                            if (flag) {
                                t.setIsSuccess(false);
                                t.setMessage("预约信息已经存在，不能重复预约");
                                log.info("info:"+ "预约信息已经存在，不能重复预约");
                                return;
                            }

                            for (String lessonScheduleId : lessonScheduleIds) {
                                appointment.setLessonScheduleId(lessonScheduleId);
                                try {
                                    appointment.setId(null);
                                    log.info("appointment:"+ JSON.toJSONString(appointment));
                                    appointmentService.addAppointment(appointment);
                                    log.info("info:"+ "add appointment success ");
                                } catch (Exception e) {
                                    e.printStackTrace();
                                    log.error("info:"+ "add appointment error ");
                                }
                                //预约码
                                int btnIdTemp = appointment.getId();
                                log.info("btnIdTemp:"+btnIdTemp);
                                bnId += btnIdTemp + ",";
                                try {
                                    Map <String, TemplateData> param = new HashMap <>();
                                    param.put("keyword1", new TemplateData(StringUtils.isEmpty(appointment.getSubscriber())?user.getTrueName():appointment.getSubscriber(), "#696969"));
                                    param.put("keyword2", new TemplateData(user.getTel(), "#696969"));
                                    String lessonAmounts="";
                                    String addr="";
                                    if(!StringUtils.isEmpty(appointment.getLessonId())){
                                        Lesson lesson = lessonService.queryLessonDetByLessonId(appointment.getLessonId());
                                        if (lesson != null) {
                                            lessonAmounts=lesson.getPrice();
                                            addr=lesson.getAddress();
                                        }
                                    }
                                    param.put("keyword3", new TemplateData(addr, "#696969"));
                                    param.put("keyword4", new TemplateData(appointment.getLessonName(), "#696969"));
                                    param.put("keyword5", new TemplateData(appointment.getReservationDate(), "#696969"));
                                    param.put("keyword6", new TemplateData(String.valueOf(appointment.getId()), "#696969"));
                                    param.put("keyword7", new TemplateData(lessonAmounts, "#696969"));

                                    Map<String,Object>miniprogram=new HashMap<>();
                                    miniprogram.put("appid",notifyPropertyConfig.getAppid());
                                    miniprogram.put("pagepath",appointment.getPage()+"?id="+appointment.getId());
                                    TempMall tempMall=TempMall.builder()
                                            .access_token(iTempMessService.getAccessToken(Token.builder()
                                                    .appid(notifyPropertyConfig.getAppid())
                                                    .secret(notifyPropertyConfig.getAppsecret())
                                                    .grant_type("client_credential")
                                                    .build()))
                                            .mp_template_msg(Mp_template_msg.builder()
                                                    .template_id(notifyPropertyConfig.getPubliceAddress().getAppointTempletId())
                                                    .appid(notifyPropertyConfig.getPubliceId())
                                                    .url("")
                                                    .miniprogram(miniprogram)
                                                    .data(param)
                                                    .build())
                                            .touser(user.getOpenId())
                                            .build();
                                    JSONObject jsonObject= iTempMessService.messSend(tempMall);
                                    log.info(jsonObject.toString());

//                                    sendTempMess(appointment, btnIdTemp, user,notifyPropertyConfig.getAppid(),notifyPropertyConfig.getAppsecret());
                                } catch (Exception e) {
                                    log.error("e:"+e.getMessage());
                                }
                            }
                            if (!"".equals(bnId)) {
                                bnId = bnId.substring(0, bnId.length() - 1);
                            }

                        } else {
                            Appointment appointment2 = new Appointment();
                            //当前登录人用户ID
                            appointment2.setUserId(currentUserId);
                            appointment2.setSubscriber(appointment.getSubscriber());
                            appointment2.setLessonId(appointment.getLessonId());
                            appointment2.setFormId(appointment.getFormId());
                            appointment2.setLessonName(appointment.getLessonName());
                            appointment2.setRemark(appointment.getRemark());
                            appointment2.setReservationDate(appointment.getReservationDate());
                            appointment2.setOrgId(appointment.getOrgId());
                            appointment2.setApproverId(appointment.getApproverId());
                            appointment2.setIsStudy(appointment.getIsStudy());
                            appointment2.setSex(appointment.getSex());
                            appointment2.setBirthday(appointment.getBirthday());
                            appointment2.setPage(appointment.getPage());

                            List <Appointment> list = appointmentService.queryAppointmentExists(appointment2);
                            if (list.size() > 0) {
                                t.setIsSuccess(false);
                                t.setMessage("预约信息已经存在，不能重复预约");
                                log.info("info:"+ "预约信息已经存在，不能重复预约");
                                return;
                            }

                            try {
                                appointment2.setId(null);
                                log.info("appointment:"+ JSON.toJSONString(appointment2));
                                appointmentService.addAppointment(appointment2);
                                log.info("info:"+ "add appointment success ");
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("info:"+ "add appointment error ");
                            }

                            //预约码
                            int btnIdTemp = appointment2.getId();
                            bnId += btnIdTemp;
//                            appointment2.setPage(appointment.getPage()+"?id="+ bnId);
                            try {
                                Map <String, TemplateData> param = new HashMap <>();
                                param.put("keyword1", new TemplateData(StringUtils.isEmpty(appointment2.getSubscriber())?user.getTrueName():appointment2.getSubscriber(), "#696969"));
                                param.put("keyword2", new TemplateData(user.getTel(), "#696969"));
                                String lessonAmounts="";
                                String addr="";
                                if(!StringUtils.isEmpty(appointment2.getLessonId())){
                                    Lesson lesson = lessonService.queryLessonDetByLessonId(appointment2.getLessonId());
                                    if (lesson != null) {
                                        lessonAmounts=lesson.getPrice();
                                        addr=lesson.getAddress();
                                    }
                                }
                                param.put("keyword3", new TemplateData(addr, "#696969"));
                                param.put("keyword4", new TemplateData(appointment2.getLessonName(), "#696969"));
                                param.put("keyword5", new TemplateData(appointment2.getReservationDate(), "#696969"));
                                param.put("keyword6", new TemplateData(String.valueOf(appointment2.getId()), "#696969"));
                                param.put("keyword7", new TemplateData(lessonAmounts, "#696969"));

                                Map<String,Object>miniprogram=new HashMap<>();
                                miniprogram.put("appid",notifyPropertyConfig.getAppid());
                                miniprogram.put("pagepath",appointment2.getPage()+"?id="+appointment2.getId());
                                TempMall tempMall=TempMall.builder()
                                        .access_token(iTempMessService.getAccessToken(Token.builder()
                                                .appid(notifyPropertyConfig.getAppid())
                                                .secret(notifyPropertyConfig.getAppsecret())
                                                .grant_type("client_credential")
                                                .build()))
                                        .mp_template_msg(Mp_template_msg.builder()
                                                .template_id(notifyPropertyConfig.getPubliceAddress().getAppointTempletId())
                                                .appid(notifyPropertyConfig.getPubliceId())
                                                .url("")
                                                .miniprogram(miniprogram)
                                                .data(param)
                                                .build())
                                        .touser(user.getOpenId())
                                        .build();
                                JSONObject jsonObject= iTempMessService.messSend(tempMall);
                                log.info(jsonObject.toString());


//                                sendTempMess(appointment2, btnIdTemp, user,notifyPropertyConfig.getAppid(),notifyPropertyConfig.getAppsecret());
                            } catch (Exception e) {
                                log.error("e:"+ e.getMessage());
                            }

                        }

                        log.info("info:"+ bnId);
                        JSONObject map = new JSONObject();
                        map.put("bnId", bnId);
                        t.setData(map);
                        log.info("info:"+ "预约成功");

                    } catch (Exception e) {
                        log.error("e:", e.getMessage());
                        t.setMessage(e.getMessage());
                        t.setIsSuccess(false);
                    }
                },
                (e, t) -> {
                    e.printStackTrace();
                    t.setIsSuccess(false);
                    t.setMessage("发起预约失败");
                    log.error("e:", e.getMessage());
                }
        );
    }

    /*
     * YT  2018/10/25 0:27
     * 方法描述：发送模板消息
     */
    @Logs
    public void sendTempMess(Appointment appointment, int bnId, User user, String appid, String appsecret) {

        //发送模板消息
//        TempMess tempMess = new TempMess();
//        tempMess.setTemplType("2");
//        tempMess.setOpenId(user.getOpenId());
//        tempMess.setFormId(appointment.getFormId());
//        tempMess.setUserId(String.valueOf(user.getId()));
//        tempMess.setTel(user.getTel());
//        tempMess.setName(StringUtils.isEmpty(appointment.getSubscriber())?user.getTrueName():appointment.getSubscriber());
//        //查询课程信息
//        if(!StringUtils.isEmpty(appointment.getLessonId())){
//            Lesson lesson = lessonService.queryLessonDetByLessonId(appointment.getLessonId());
//            if (lesson != null) {
//                tempMess.setLessonAmounts(lesson.getPrice());
//                tempMess.setAddr(lesson.getAddress());
//            }
//        }
//
//        tempMess.setLessonName(appointment.getLessonName());
//        tempMess.setReservationCode(String.valueOf(bnId));
//        tempMess.setReservationDate(appointment.getReservationDate());
//        tempMess.setPage(appointment.getPage());
//        iTempMessService.send(tempMess,appid,appsecret);
    }
}